package com.sun.huazhi.aitaskservice.controller;

import com.sun.huazhi.aitaskservice.DTO.response.KnowledgeUploadResponse;
import com.sun.huazhi.aitaskservice.common.config.PythonApiProperties;
import com.sun.huazhi.aitaskservice.common.resilience.ResilientServiceExecutor;
import com.sun.huazhi.aitaskservice.common.utils.FileTypeValidator;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.*;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;


@RestController
@Tag(name = "知识库管理", description = "提供插花艺术知识库文档的上传功能")
@RequestMapping("/api/knowledge")
@Slf4j
public class KnowledgeController {

    private static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB

    @Autowired
    @Qualifier("pythonApiProperties")
    private PythonApiProperties apiProps;

    @Autowired
    private WebClient webClient;

    @Autowired
    private ResilientServiceExecutor resilientExecutor;

    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "上传知识文档", description = "向插花艺术知识库添加新的文档资料（PDF/TXT/DOCX）")
    public Mono<ResponseEntity<KnowledgeUploadResponse>> uploadKnowledge(@RequestPart("file") FilePart filePart) {
        String contentType = filePart.headers().getContentType().toString();
        log.info("接收到上传文件请求: 文件名={}, 类型={}", filePart.filename(), contentType);

        if (!FileTypeValidator.isAllowedContentType(contentType)) {
            log.warn("非法文件类型: {}", contentType);
            return Mono.just(ResponseEntity
                    .badRequest()
                    .body(new KnowledgeUploadResponse("不支持的文件类型")));
        }

        Mono<Resource> fileResourceMono = filePart.content().collectList().map(dataBuffers -> {
            int totalSize = dataBuffers.stream().mapToInt(DataBuffer::readableByteCount).sum();
            if (totalSize > MAX_FILE_SIZE) {
                throw new IllegalArgumentException("文件大小超出限制（最大10MB）");
            }

            byte[] bytes = new byte[totalSize];
            int offset = 0;
            for (DataBuffer buffer : dataBuffers) {
                int len = buffer.readableByteCount();
                buffer.read(bytes, offset, len);
                DataBufferUtils.release(buffer);
                offset += len;
            }

            return new ByteArrayResource(bytes) {
                @Override
                public String getFilename() {
                    return filePart.filename();
                }
            };
        });

        return resilientExecutor.execute(() ->
                fileResourceMono.flatMap(resource -> webClient.post()
                        .uri(apiProps.getUrl() + "/upload-knowledge")
                        .contentType(MediaType.MULTIPART_FORM_DATA)
                        .body(BodyInserters.fromMultipartData("file", resource))
                        .retrieve()
                        .bodyToMono(KnowledgeUploadResponse.class)
                        .map(ResponseEntity::ok)
                        .doOnSuccess(resp -> log.info("上传成功: {}", resp.getBody()))
                        .doOnError(err -> log.error("上传失败: {}", err.getMessage()))
                )
        );
    }
}
